home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-06 | 29.2 KB | 1,475 lines |
- Newsgroups: comp.sources.misc
- From: kyle@nick.csh.rit.edu (Kyle Saunders)
- Subject: v25i034: genmake - automatically generate a Makefile, Part01/01
- Message-ID: <1991Nov6.050248.8175@sparky.imd.sterling.com>
- X-Md4-Signature: ef032e1252406a3c250292a3997eece6
- Date: Wed, 6 Nov 1991 05:02:48 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: kyle@nick.csh.rit.edu (Kyle Saunders)
- Posting-number: Volume 25, Issue 34
- Archive-name: genmake/part01
- Environment: BSD
-
- This is genmake, version 1.03. As the name implies, it will
- automatically generate a Makefile for a single target. The
- only supported language is K&R C. Basically, you run genmake
- in the directory of your project. Genmake will grind away and
- produce a Makefile.
-
- Genmake has the following options:
-
- -v - prints version info
-
- -i - interactive prompt to include a file when it
- contains routines that are not used
-
- -e - exhaustive analysis. Basically, will check
- functional dependencies, and report if all
- functions in a file are never used. Takes quite
- a bit longer to run.
-
- kyle@nick.csh.rit.edu
- -------
- # This is a shell archive. Save it in a file, remove anything before
- # this line, and then unpack it by entering "sh file". Note, it may
- # create directories; files and directories will be owned by you and
- # have default permissions.
- #
- # This archive contains:
- #
- # README
- # Makefile
- # consts.h
- # err.h
- # opts.h
- # types.h
- # version.h
- # build.c
- # cpp.c
- # genmake.c
- # makef.c
- # nodes.c
- # parse.c
- # print_deps.c
- # valid.c
- #
- echo x - README
- sed 's/^X//' >README << 'END-of-README'
- X
- X This is genmake, version 1.03. As the name implies, it will
- Xautomatically generate a Makefile for a single target. The only supported
- Xlanguage is K&R C.
- X
- X Basically, you run genmake in the directory of your project. Genmake
- Xwill grind away and produce a Makefile.
- X
- X Genmake has the following options:
- X
- X -v - prints version info
- X
- X -i - interactive prompt to include a file when it
- X contains routines that are not used
- X
- X -e - exhaustive analysis. Basically, will check
- X functional dependencies, and report if all
- X functions in a file are never used. Takes quite
- X a bit longer to run.
- X
- X
- X Genmake 1.03 is (c)1990, 1991 by Kyle Saunders, All Rights Reserved
- X kyle@nick.csh.rit.edu
- X kxs5829@ultb.isc.rit.edu
- X
- X This program is Freely Distributable
- X
- END-of-README
- echo x - Makefile
- sed 's/^X//' >Makefile << 'END-of-Makefile'
- X#Genmake v1.03 10/30/91 Copyright(c) 1990, 1991 by Kyle Saunders
- XCC= gcc
- XCOPTS= -O
- XOFILES= \
- X parse.o\
- X genmake.o\
- X nodes.o\
- X build.o\
- X print_deps.o\
- X valid.o\
- X makef.o\
- X cpp.o
- X#
- Xgenmake: $(OFILES)
- X $(CC) $(COPTS) -o genmake $(OFILES)
- X
- Xtypes.h: \
- X consts.h\
- X version.h
- X touch types.h
- X
- Xparse.o: types.h\
- X parse.c
- X $(CC) $(COPTS) -c parse.c
- X
- Xgenmake.o: types.h\
- X genmake.c\
- X opts.h\
- X err.h
- X $(CC) $(COPTS) -c genmake.c
- X
- Xnodes.o: types.h\
- X nodes.c
- X $(CC) $(COPTS) -c nodes.c
- X
- Xbuild.o: types.h\
- X build.c
- X $(CC) $(COPTS) -c build.c
- X
- Xprint_deps.o: types.h\
- X print_deps.c
- X $(CC) $(COPTS) -c print_deps.c
- X
- Xvalid.o: types.h\
- X valid.c
- X $(CC) $(COPTS) -c valid.c
- X
- Xconsts.h:
- X touch consts.h
- X
- Xopts.h:
- X touch opts.h
- X
- Xmakef.o: types.h\
- X makef.c
- X $(CC) $(COPTS) -c makef.c
- X
- Xerr.h:
- X touch err.h
- X
- Xversion.h:
- X touch version.h
- X
- Xcpp.o: types.h\
- X cpp.c
- X $(CC) $(COPTS) -c cpp.c
- X
- END-of-Makefile
- echo x - consts.h
- sed 's/^X//' >consts.h << 'END-of-consts.h'
- X/* consts.h */
- X
- X#define CSOURCE 1
- X#define CHEADER 2
- X
- X#define BUFSIZE 512
- END-of-consts.h
- echo x - err.h
- sed 's/^X//' >err.h << 'END-of-err.h'
- X/* err.h */
- X
- X#define ERRFINDMAIN 1
- X#define ERRBUILDDEP 2
- X#define ERRCREATEMF 3
- X#define ERROPTION 4
- END-of-err.h
- echo x - opts.h
- sed 's/^X//' >opts.h << 'END-of-opts.h'
- X/* opts.h */
- X
- X#define VERSION 'v'
- X#define VERBATIM 'V'
- X#define EXHAUSTIVE 'e'
- X#define INTERACT 'i'
- X#define HELP 'h'
- END-of-opts.h
- echo x - types.h
- sed 's/^X//' >types.h << 'END-of-types.h'
- X/* types.h */
- X
- X#include "consts.h"
- X#include "version.h"
- X
- Xextern int errno;
- X
- Xtypedef struct file_node {
- X char *name; /* file name */
- X struct file_node *next;
- X} FNODE;
- X
- Xtypedef struct depend_node {
- X char *name; /* file name */
- X FNODE *dlist; /* list of files that depend
- X on this one */
- X int use_it;
- X struct depend_node *next;
- X} DNODE;
- X
- Xtypedef struct opt_node {
- X int version;
- X int verbatim;
- X int exhaustive;
- X int interactive;
- X} OPTS;
- X
- Xtypedef struct cpp_node {
- X int expr_val;
- X int in_else;
- X struct cpp_node *next;
- X} CPPN;
- X
- Xtypedef struct sym_ent {
- X char *name;
- X struct sym_ent *next;
- X} SYMENT;
- X
- END-of-types.h
- echo x - version.h
- sed 's/^X//' >version.h << 'END-of-version.h'
- X/* version.h */
- X
- X#define BANNER "Genmake v1.03 10/30/91 Copyright(c) 1990, 1991 by Kyle Saunders"
- END-of-version.h
- echo x - build.c
- sed 's/^X//' >build.c << 'END-of-build.c'
- X/* build.c */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include "types.h"
- X
- XDNODE *add_dep_node();
- XFNODE *add_file_node();
- X
- X/* goes through the current directory build the dep list for each file */
- X
- Xbuild_depends(make_list,opts,mname)
- XDNODE **make_list;
- XOPTS *opts;
- Xchar *mname;
- X{
- X DIR *dirp;
- X struct direct *dp;
- X DNODE *new;
- X int is_dep;
- X char ask[BUFSIZE];
- X
- X if ((dirp = opendir(".")) == NULL) {
- X fprintf(stderr,"build_depends(): can't open directory\n");
- X return(0);
- X }
- X /* for each file in the directory */
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X /* is it a recognisable source file */
- X if (!valid_source_file(dp->d_name))
- X continue;
- X if ((new = add_dep_node(make_list,dp->d_name)) == NULL) {
- X closedir(dirp);
- X return(0);
- X }
- X /* a file depends on itself */
- X add_file_node(new,dp->d_name);
- X /* create the dependency list for the current file */
- X if ((is_dep = build_dep_list(new,opts)) == 0) {
- X closedir(dirp);
- X return(0);
- X }
- X if (opts->exhaustive == 1 && is_dep == 1 && strcmp(new->name,mname)) {
- X fprintf(stderr,"Warning: no one else uses file %s\n",new->name);
- X if (opts->interactive) {
- X printf("Include file in Makefile(Y/N)? ");
- X gets(ask);
- X if (ask[0] != 'Y' && ask[0] != 'y')
- X new->use_it = 0;
- X }
- X else
- X new->use_it = 0;
- X }
- X }
- X closedir(dirp);
- X return(1);
- X}
- X
- Xbuild_dep_list(dnode,opts)
- XDNODE *dnode;
- XOPTS *opts;
- X{
- X FILE *fp;
- X int count = 0;
- X int cp = 0;
- X int stype;
- X int cont;
- X char buf[BUFSIZE];
- X char func_name[BUFSIZE];
- X int aok;
- X int is_dep = 0;
- X CPPN **cpp_stack;
- X SYMENT **symtab;
- X
- X stype = valid_source_file(dnode->name);
- X if (opts->exhaustive == 0 && stype == CSOURCE)
- X return(1);
- X if ((fp = fopen(dnode->name,"r")) == NULL) {
- X fprintf(stderr,"build_dep_list: can't open %s\n",dnode->name);
- X return(0);
- X }
- X cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
- X *cpp_stack = NULL;
- X symtab = (SYMENT **)malloc(sizeof(SYMENT *));
- X *symtab = NULL;
- X buf[0] = NULL;
- X func_name[0] = NULL;
- X /* forever */
- X for (;;) {
- X cont = 1;
- X switch (stype) {
- X /* get the next function definition */
- X case CSOURCE: cont = parse_file(fp,func_name,&count,buf,&cp,cpp_stack,symtab);
- X break;
- X default: ;
- X }
- X /* if we are done with the file, stop */
- X if (!cont)
- X break;
- X /* add the dependencies */
- X if ((aok = depend_on_it(dnode,func_name)) == 0) {
- X cpp_rel(cpp_stack,symtab);
- X fclose(fp);
- X return(0);
- X }
- X if (aok == 2)
- X is_dep = 1;
- X if (stype == CHEADER)
- X break;
- X }
- X cpp_rel(cpp_stack,symtab);
- X fclose(fp);
- X return(is_dep+1);
- X}
- X
- Xdepend_on_it(dnode,func_name)
- XDNODE *dnode;
- Xchar *func_name;
- X{
- X DIR *dirp;
- X struct direct *dp;
- X int stype;
- X int aok;
- X int is_dep = 0;
- X
- X#ifdef DEBUG
- X printf("depend_on_it(): dnode->name= '%s'\nfunc_name= '%s'\n",dnode->name,func_name);
- X#endif
- X stype = valid_source_file(dnode->name);
- X if ((dirp = opendir(".")) == NULL) {
- X fprintf(stderr,"depend_on_it(): Can't open directory\n");
- X return(0);
- X }
- X /* for each file in the directory */
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X if (!valid_source_file(dp->d_name) || in_file_list(dnode,dp->d_name))
- X continue;
- X switch (stype) {
- X case CSOURCE: aok = depends(dp->d_name,func_name);
- X break;
- X case CHEADER: aok = hdepends(dp->d_name,dnode->name);
- X break;
- X }
- X /* if we found a dependency, add the current file to list */
- X if (aok) {
- X is_dep = 1;
- X if (add_file_node(dnode,dp->d_name) == NULL) {
- X closedir(dirp);
- X return(0);
- X }
- X }
- X }
- X closedir(dirp);
- X return(is_dep+1);
- X}
- END-of-build.c
- echo x - cpp.c
- sed 's/^X//' >cpp.c << 'END-of-cpp.c'
- X/* cpp.c */
- X
- X#include <stdio.h>
- X#include "types.h"
- X
- X/* quick hack to get a cpp front end going */
- X
- Xcpp_parse(buf,cpp_stack,symtab)
- Xchar *buf;
- XCPPN **cpp_stack;
- XSYMENT **symtab;
- X{
- X char tok[BUFSIZE];
- X char tok2[BUFSIZE];
- X int cp = 0;
- X
- X if (buf[0] != '#')
- X return(0);
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X if (!strcmp("define",tok) && cpp_useline(cpp_stack)) {
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X add_sym(symtab,tok);
- X }
- X else if (!strcmp("undef",tok) && cpp_useline(cpp_stack)) {
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X del_sym(symtab,tok);
- X }
- X else if (!strcmp("ifdef",tok) && cpp_useline(cpp_stack)) {
- X#ifdef DEBUG
- X printf("#ifdef\n");
- X#endif
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X if (find_sym(symtab,tok))
- X push_if(cpp_stack,1);
- X else
- X push_if(cpp_stack,0);
- X }
- X else if (!strcmp("ifndef",tok) && cpp_useline(cpp_stack)) {
- X#ifdef DEBUG
- X printf("#ifndef\n");
- X#endif
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X if (!find_sym(symtab,tok))
- X push_if(cpp_stack,1);
- X else
- X push_if(cpp_stack,0);
- X }
- X else if (!strcmp("if",tok) && cpp_useline(cpp_stack)) {
- X#ifdef DEBUG
- X printf("#if\n");
- X#endif
- X /* fprintf(stderr,"Warning: #if not supported\n"); */
- X push_if(cpp_stack,1);
- X }
- X else if (!strcmp("else",tok)) {
- X#ifdef DEBUG
- X printf("#else\n");
- X#endif
- X set_else(cpp_stack);
- X }
- X else if (!strcmp("endif",tok)) {
- X#ifdef DEBUG
- X printf("#endif\n");
- X#endif
- X pop_if(cpp_stack);
- X }
- X else if (!strcmp("include",tok) && cpp_useline(cpp_stack)) {
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X if (tok[0] == '<') {
- X char itok[BUFSIZE];
- X
- X itok[0] = '\0';
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X while (tok[0] != '>') {
- X strcat(itok,tok);
- X if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
- X return(0);
- X }
- X sprintf(tok2,"/usr/include/%s",itok);
- X if (!cpp_include(cpp_stack,symtab,tok2))
- X return(-1);
- X } else if (tok[0] == '\"') {
- X int i;
- X
- X for (i = 1; tok[i] != '\"' && tok[i] != NULL; i++)
- X tok2[i-1] = tok[i];
- X tok2[i-1] = NULL;
- X if (!cpp_include(cpp_stack,symtab,tok2))
- X return(-1);
- X }
- X }
- X return(1);
- X}
- X
- Xcpp_useline(cpp_stack)
- XCPPN **cpp_stack;
- X{
- X CPPN *cur;
- X
- X if (*cpp_stack == NULL) {
- X return(1);
- X }
- X cur = *cpp_stack;
- X if (cur->expr_val != 0 && cur->in_else == 0) {
- X return(1);
- X }
- X else if (cur->expr_val == 0 && cur->in_else != 0) {
- X return(1);
- X }
- X else {
- X return(0);
- X }
- X}
- X
- Xcpp_rel(cpp_stack,symtab)
- XCPPN **cpp_stack;
- XSYMENT **symtab;
- X{
- X CPPN *cur;
- X CPPN *next;
- X SYMENT *scur;
- X SYMENT *snext;
- X
- X cur = *cpp_stack;
- X while (cur != NULL) {
- X next = cur->next;
- X free(cur);
- X cur = next;
- X }
- X free(cpp_stack);
- X scur = *symtab;
- X while (scur != NULL) {
- X snext = scur->next;
- X free(scur->name);
- X free(scur);
- X scur = snext;
- X }
- X free(symtab);
- X}
- X
- Xadd_sym(symtab,name)
- XSYMENT **symtab;
- Xchar *name;
- X{
- X SYMENT *cur;
- X SYMENT *prev;
- X SYMENT *new;
- X
- X if (find_sym(symtab,name) != NULL)
- X return(1);
- X prev = NULL;
- X cur = *symtab;
- X while (cur != NULL) {
- X prev = cur;
- X if (!strcmp(cur->name,name))
- X break;
- X cur = cur->next;
- X }
- X if (cur != NULL)
- X return(1);
- X new = (SYMENT *)malloc(sizeof(SYMENT));
- X new->name = (char *)malloc(strlen(name)+1);
- X strcpy(new->name,name);
- X new->next = NULL;
- X if (prev == NULL)
- X *symtab = new;
- X else
- X prev->next = new;
- X return(1);
- X}
- X
- Xdel_sym(symtab,name)
- XSYMENT **symtab;
- Xchar *name;
- X{
- X SYMENT *cur;
- X SYMENT *prev;
- X
- X prev = NULL;
- X cur = *symtab;
- X while (cur != NULL) {
- X if (!strcmp(cur->name,name))
- X break;
- X prev = cur;
- X cur = cur->next;
- X }
- X if (cur == NULL)
- X return(0);
- X if (prev == NULL) {
- X free(cur->name);
- X free(cur);
- X *symtab = NULL;
- X }
- X else {
- X prev->next = cur->next;
- X free(cur->name);
- X free(cur);
- X }
- X return(1);
- X}
- X
- Xfind_sym(symtab,name)
- XSYMENT **symtab;
- Xchar *name;
- X{
- X SYMENT *cur;
- X
- X cur = *symtab;
- X while (cur != NULL) {
- X#ifdef DEBUG
- X printf("cur->name = '%s'\n",cur->name);
- X#endif
- X if (!strcmp(cur->name,name))
- X break;
- X cur = cur->next;
- X }
- X if (cur != NULL)
- X return(1);
- X return(0);
- X}
- X
- Xpush_if(cpp_stack,val)
- XCPPN **cpp_stack;
- Xint val;
- X{
- X CPPN *new;
- X
- X new = (CPPN *)malloc(sizeof(CPPN));
- X new->expr_val = val;
- X new->in_else = 0;
- X new->next = *cpp_stack;
- X *cpp_stack = new;
- X}
- X
- Xset_else(cpp_stack)
- XCPPN **cpp_stack;
- X{
- X CPPN *cur;
- X
- X cur = *cpp_stack;
- X if (cur == NULL) {
- X/*
- X fprintf(stderr,"#else without matching #if[[n]def]\n");
- X*/
- X return;
- X }
- X cur->in_else = 1;
- X}
- X
- Xpop_if(cpp_stack)
- XCPPN **cpp_stack;
- X{
- X CPPN *next;
- X CPPN *cur;
- X
- X cur = *cpp_stack;
- X if (cur == NULL) {
- X/*
- X fprintf(stderr,"#endif without matching #if[[n]def]\n");
- X*/
- X return;
- X }
- X next = cur->next;
- X free(cur);
- X *cpp_stack = next;
- X}
- X
- Xcpp_include(cpp_stack,symtab,name)
- XCPPN **cpp_stack;
- XSYMENT **symtab;
- Xchar *name;
- X{
- X char buf[BUFSIZE];
- X char tok[BUFSIZE];
- X int cp;
- X FILE *fp;
- X
- X#ifdef DEBUG
- X printf("#include file = '%s'\n",name);
- X#endif
- X if ((fp = fopen(name,"r")) == NULL) {
- X fprintf(stderr,"cpp_include(): can't open file '%s'\n",name);
- X return(0);
- X }
- X buf[0] = NULL;
- X cp = 0;
- X while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0)
- X ;
- X#ifdef DEBUG
- X printf("ending #include file = '%s'\n",name);
- X#endif
- X fclose(fp);
- X return(1);
- X}
- END-of-cpp.c
- echo x - genmake.c
- sed 's/^X//' >genmake.c << 'END-of-genmake.c'
- X/* genmake.c */
- X
- X#include <stdio.h>
- X#include "opts.h"
- X#include "types.h"
- X#include "err.h"
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X DNODE **make_list;
- X OPTS *opts;
- X char mname[BUFSIZE];
- X
- X opts = (OPTS *)malloc(sizeof(OPTS));
- X parse_options(argc,argv,opts);
- X make_list = (DNODE **)malloc(sizeof(DNODE *));
- X *make_list = NULL;
- X if (!find_main_target(opts,mname)) {
- X free(opts);
- X free_list(make_list);
- X exit(ERRFINDMAIN);
- X }
- X printf("main(): %s\n",mname);
- X if (build_depends(make_list,opts,mname) == 0) {
- X free(opts);
- X free_list(make_list);
- X exit(ERRBUILDDEP);
- X }
- X if (!make_file(make_list,opts,mname)) {
- X free(opts);
- X free_list(make_list);
- X exit(ERRCREATEMF);
- X }
- X free(opts);
- X free_list(make_list);
- X return(0);
- X}
- X
- Xparse_options(argc,argv,opts)
- Xint argc;
- Xchar *argv[];
- XOPTS *opts;
- X{
- X int argn;
- X
- X opts->verbatim = 0;
- X opts->exhaustive = 0;
- X opts->interactive = 0;
- X for (argn = 1; argn < argc; argn++) {
- X if (argv[argn][0] == '-') {
- X switch (argv[argn][1]) {
- X case VERSION: credits();
- X break;
- X case HELP: help();
- X free(opts);
- X exit(0);
- X break;
- X case VERBATIM: opts->verbatim = 1;
- X break;
- X case EXHAUSTIVE:opts->exhaustive = 1;
- X break;
- X case INTERACT: opts->interactive = 1;
- X break;
- X default: option_error(argv[argn],opts);
- X break;
- X }
- X }
- X }
- X}
- X
- Xoption_error(o,opts)
- Xchar *o;
- XOPTS *opts;
- X{
- X fprintf(stderr,"genmake: unknown option '%c'\n",o[1]);
- X help();
- X free(opts);
- X exit(ERROPTION);
- X}
- X
- Xcredits()
- X{
- X printf("%s\n",BANNER);
- X}
- X
- Xhelp()
- X{
- X printf("Usage: genmake [-v] [-i] [-e]\n");
- X}
- X
- END-of-genmake.c
- echo x - makef.c
- sed 's/^X//' >makef.c << 'END-of-makef.c'
- X/* makef.c */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include "types.h"
- X
- XDNODE *last_node();
- XDNODE *find_dep();
- X
- Xmake_file(make_list,opts,mname)
- XDNODE **make_list;
- XOPTS *opts;
- Xchar *mname;
- X{
- X FILE *fp;
- X DNODE *out;
- X DNODE *in;
- X DNODE *last;
- X int count;
- X int type;
- X char name[BUFSIZE];
- X
- X if ((fp = fopen("Makefile","w")) == NULL) {
- X fprintf(stderr,"make_file(): can't open Makefile for writing\n");
- X return(0);
- X }
- X if (!macros(make_list,fp,opts,mname)) {
- X fclose(fp);
- X return(0);
- X }
- X for (out = *make_list; out != NULL; out = out->next) {
- X if (target(out->name,name) && out->use_it) {
- X type = valid_source_file(out->name);
- X fprintf(fp,"%s:\t",name);
- X last = last_node(make_list,out->name);
- X count = 0;
- X for (in = *make_list; in != NULL; in = in->next) {
- X if (valid_source_file(in->name) == CSOURCE &&
- X strcmp(in->name,out->name))
- X continue;
- X if (in_file_list(in,out->name)) {
- X ++count;
- X if (strcmp(in->name,name))
- X write_dep(fp,count,in,last,in->name);
- X else
- X write_dep(fp,count,in,last,"");
- X }
- X }
- X write_command(fp,out->name,type,opts);
- X }
- X }
- X fclose(fp);
- X return(1);
- X}
- X
- Xwrite_command(fp,name,type,opts)
- XFILE *fp;
- Xchar *name;
- Xint type;
- XOPTS *opts;
- X{
- X switch (type) {
- X case CSOURCE: fprintf(fp,"\t\t$(CC) $(COPTS) -c %s\n\n",name);
- X break;
- X case CHEADER: fprintf(fp,"\t\ttouch %s\n\n",name);
- X break;
- X }
- X}
- X
- Xwrite_dep(fp,count,in,last,name)
- XFILE *fp;
- Xint count;
- XDNODE *in;
- XDNODE *last;
- Xchar *name;
- X{
- X if (count == 1 && in != last)
- X fprintf(fp,"%s\\\n",name);
- X else if (count == 1)
- X fprintf(fp,"%s\n",name);
- X else if (in == last)
- X fprintf(fp,"\t\t%s\n",name);
- X else
- X fprintf(fp,"\t\t%s\\\n",name);
- X}
- X
- XDNODE *
- Xlast_node(make_list,name)
- XDNODE **make_list;
- Xchar *name;
- X{
- X DNODE *last = NULL;
- X DNODE *in;
- X
- X for (in = *make_list; in != NULL; in = in->next) {
- X if (valid_source_file(in->name) == CSOURCE &&
- X strcmp(in->name,name))
- X continue;
- X if (in_file_list(in,name))
- X last = in;
- X }
- X return(last);
- X}
- X
- Xmacros(make_list,fp,opts,mname)
- XDNODE **make_list;
- XFILE *fp;
- XOPTS *opts;
- Xchar *mname;
- X{
- X fprintf(fp,"#%s\n",BANNER);
- X fprintf(fp,"CC= cc\n");
- X fprintf(fp,"COPTS= -g\n");
- X fprintf(fp,"OFILES= \\\n");
- X if (!ofiles(make_list,fp,opts))
- X return(0);
- X fprintf(fp,"#\n");
- X if (!main_target(fp,opts,mname))
- X return(0);
- X return(1);
- X}
- X
- Xofiles(make_list,fp,opts)
- XDNODE **make_list;
- XFILE *fp;
- XOPTS *opts;
- X{
- X DNODE *cur;
- X DIR *dirp;
- X struct direct *dp;
- X int type;
- X char name[BUFSIZE];
- X char last[BUFSIZE];
- X
- X if ((dirp = opendir(".")) == NULL) {
- X fprintf(stderr,"ofiles(): can't open directory\n");
- X return(0);
- X }
- X if (!last_ofile(make_list,opts,last)) {
- X closedir(dirp);
- X return(0);
- X }
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X type = valid_source_file(dp->d_name);
- X if ((cur = find_dep(make_list,dp->d_name)) == NULL)
- X continue;
- X if (type == CSOURCE && target(dp->d_name,name) && cur->use_it)
- X if (strcmp(last,dp->d_name))
- X fprintf(fp,"\t%s\\\n",name);
- X else
- X fprintf(fp,"\t%s\n",name);
- X }
- X closedir(dirp);
- X return(1);
- X}
- X
- Xlast_ofile(make_list,opts,last)
- XDNODE **make_list;
- XOPTS *opts;
- Xchar *last;
- X{
- X DNODE *cur;
- X DIR *dirp;
- X struct direct *dp;
- X int type;
- X char name[BUFSIZE];
- X
- X if ((dirp = opendir(".")) == NULL) {
- X fprintf(stderr,"last_ofile(): can't open directory\n");
- X return(0);
- X }
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X type = valid_source_file(dp->d_name);
- X if ((cur = find_dep(make_list,dp->d_name)) == NULL)
- X continue;
- X if (type == CSOURCE && target(dp->d_name,name) && cur->use_it)
- X strcpy(last,dp->d_name);
- X }
- X closedir(dirp);
- X return(1);
- X}
- X
- Xfind_main_target(opts,mname)
- XOPTS *opts;
- Xchar *mname;
- X{
- X DIR *dirp;
- X struct direct *dp;
- X int type;
- X int count = 0;
- X
- X if ((dirp = opendir(".")) == NULL) {
- X fprintf(stderr,"main_target(): can't open directory\n");
- X return(0);
- X }
- X mname[0] = NULL;
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X type = valid_source_file(dp->d_name);
- X if (type == CSOURCE)
- X if (depends(dp->d_name,"main")) {
- X if (++count > 1)
- X fprintf(stderr,"Warning: main() multiply defined: %s\n",dp->d_name);
- X strcpy(mname,dp->d_name);
- X }
- X
- X }
- X closedir(dirp);
- X return(1);
- X}
- X
- Xmain_target(fp,opts,mname)
- XFILE *fp;
- XOPTS *opts;
- Xchar *mname;
- X{
- X int i;
- X char name[BUFSIZE];
- X
- X strcpy(name,mname);
- X for (i = 0; name[i] != '.' && name[i] != NULL; i++)
- X ;
- X name[i] = NULL;
- X fprintf(fp,"%s:\t$(OFILES)\n",name);
- X fprintf(fp,"\t\t$(CC) $(COPTS) -o %s $(OFILES)\n\n",name);
- X return(1);
- X}
- X
- Xtarget(old,new)
- Xchar *old;
- Xchar *new;
- X{
- X int i;
- X
- X strcpy(new,old);
- X for (i = 0; old[i] != '.' && old[i] != NULL; i++)
- X ;
- X if (old[i] == NULL)
- X return(0);
- X if (!strcmp(&old[i+1],"c"))
- X new[i+1] = 'o';
- X else if (!strcmp(&old[i+1],"h"))
- X ;
- X else
- X return(0);
- X return(1);
- X}
- END-of-makef.c
- echo x - nodes.c
- sed 's/^X//' >nodes.c << 'END-of-nodes.c'
- X/* nodes.c */
- X
- X#include <stdio.h>
- X#include "types.h"
- X
- XDNODE *
- Xadd_dep_node(make_list,name)
- XDNODE **make_list;
- Xchar *name;
- X{
- X DNODE *prev;
- X DNODE *cur;
- X DNODE *new;
- X
- X for (prev = NULL, cur = *make_list; cur != NULL; cur = cur->next)
- X prev = cur;
- X new = (DNODE *)malloc(sizeof(DNODE));
- X new->name = (char *)malloc(strlen(name)+1);
- X strcpy(new->name,name);
- X new->next = NULL;
- X new->dlist = NULL;
- X new->use_it = 1;
- X if (prev == NULL)
- X *make_list = new;
- X else
- X prev->next = new;
- X return(new);
- X}
- X
- XFNODE *
- Xadd_file_node(dnode,name)
- XDNODE *dnode;
- Xchar *name;
- X{
- X FNODE *prev;
- X FNODE *cur;
- X FNODE *new;
- X
- X for (prev = NULL, cur = dnode->dlist; cur != NULL; cur = cur->next)
- X prev = cur;
- X new = (FNODE *)malloc(sizeof(FNODE));
- X new->name = (char *)malloc(strlen(name)+1);
- X strcpy(new->name,name);
- X new->next = NULL;
- X if (prev == NULL)
- X dnode->dlist = new;
- X else
- X prev->next = new;
- X return(new);
- X}
- X
- Xin_file_list(dnode,name)
- XDNODE *dnode;
- Xchar *name;
- X{
- X FNODE *cur;
- X
- X for (cur = dnode->dlist; cur != NULL; cur = cur->next)
- X if (!strcmp(cur->name,name))
- X return(1);
- X return(0);
- X}
- X
- XDNODE *
- Xfind_dep(make_list,name)
- XDNODE **make_list;
- Xchar *name;
- X{
- X DNODE *cur;
- X
- X for (cur = *make_list; cur != NULL; cur = cur->next)
- X if (!strcmp(cur->name,name))
- X return(cur);
- X return(NULL);
- X}
- X
- Xfree_list(make_list)
- XDNODE **make_list;
- X{
- X DNODE *cur;
- X DNODE *next;
- X
- X cur = *make_list;
- X while (cur != NULL) {
- X next = cur->next;
- X free(cur->name);
- X free_fnodes(cur->dlist);
- X free(cur);
- X cur = next;
- X }
- X}
- X
- Xfree_fnodes(dlist)
- XFNODE *dlist;
- X{
- X FNODE *next;
- X
- X while (dlist != NULL) {
- X next = dlist->next;
- X free(dlist->name);
- X free(dlist);
- X dlist = next;
- X }
- X}
- END-of-nodes.c
- echo x - parse.c
- sed 's/^X//' >parse.c << 'END-of-parse.c'
- X/* parse.c */
- X
- X#include <stdio.h>
- X#include "types.h"
- X
- Xint sp;
- X
- Xparse_file(fp,fname,count,buf,curp,cpp_stack,symtab)
- XFILE *fp;
- Xchar *fname;
- Xint *count;
- Xchar *buf;
- Xint *curp;
- XCPPN **cpp_stack;
- XSYMENT **symtab;
- X{
- X int not_empty;
- X int lb_count = *count;
- X char tok[BUFSIZE];
- X int cp = *curp;
- X
- X while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
- X if (tok[0] == '{') {
- X ++lb_count;
- X } else if (tok[0] == '}') {
- X --lb_count;
- X } else {
- X if (lb_count > 0)
- X continue;
- X /* possible function definition, 1st ed K&R */
- X strcpy(fname,tok);
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
- X return(0);
- X if (tok[0] != '(') {
- X cp = sp;
- X continue;
- X }
- X not_empty = 0;
- X while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0 && tok[0] != ')') {
- X not_empty = 1;
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
- X return(0);
- X if (tok[0] == ')')
- X break;
- X }
- X if (cp < 0)
- X return(0);
- X if (!not_empty) {
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
- X return(0);
- X if (tok[0] != '{')
- X continue;
- X ++lb_count;
- X }
- X *curp = cp;
- X *count = lb_count;
- X return(1);
- X }
- X }
- X return(0);
- X}
- X
- X
- Xdepends(filename,funcname)
- Xchar *filename;
- Xchar *funcname;
- X{
- X FILE *fp;
- X char tok[BUFSIZE];
- X char buf[BUFSIZE];
- X char cur_func[BUFSIZE];
- X int cp = 0;
- X CPPN **cpp_stack;
- X SYMENT **symtab;
- X
- X cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
- X *cpp_stack = NULL;
- X symtab = (SYMENT **)malloc(sizeof(SYMENT *));
- X *symtab = NULL;
- X if ((fp = fopen(filename,"r")) == NULL) {
- X fprintf(stderr,"depends(): can't open file %s\n",filename);
- X cpp_rel(cpp_stack,symtab);
- X return(0);
- X }
- X cur_func[BUFSIZE] = NULL;
- X buf[0] = NULL;
- X while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
- X if (!strcmp(tok,funcname)) {
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
- X fclose(fp);
- X cpp_rel(cpp_stack,symtab);
- X return(0);
- X }
- X if (tok[0] == '(') {
- X fclose(fp);
- X cpp_rel(cpp_stack,symtab);
- X return(1);
- X }
- X cp = sp;
- X }
- X }
- X fclose(fp);
- X cpp_rel(cpp_stack,symtab);
- X return(0);
- X}
- X
- Xhdepends(filename,sname)
- Xchar *filename;
- Xchar *sname;
- X{
- X FILE *fp;
- X char tok[BUFSIZE];
- X char buf[BUFSIZE];
- X char name[BUFSIZE];
- X int cp = 0;
- X CPPN **cpp_stack;
- X SYMENT **symtab;
- X
- X cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
- X *cpp_stack = NULL;
- X symtab = (SYMENT **)malloc(sizeof(SYMENT *));
- X *symtab = NULL;
- X if ((fp = fopen(filename,"r")) == NULL) {
- X fprintf(stderr,"depends(): can't open file %s\n",filename);
- X return(0);
- X }
- X strcpy(name,"\"");
- X strcat(name,sname);
- X strcat(name,"\"");
- X buf[0] = NULL;
- X while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
- X if (tok[0] == '#' && sp == 0) {
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
- X fclose(fp);
- X return(0);
- X }
- X if (!strcmp("include",tok)) {
- X if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
- X fclose(fp);
- X return(0);
- X }
- X if (!strcmp(name,tok)) {
- X fclose(fp);
- X return(1);
- X }
- X }
- X }
- X }
- X fclose(fp);
- X return(0);
- X}
- X
- Xgettok(fp,buf,curtok,cp,cpp_stack,symtab)
- XFILE *fp;
- Xchar *buf;
- Xchar *curtok;
- Xint cp;
- XCPPN **cpp_stack;
- XSYMENT **symtab;
- X{
- X int quote = 0;
- X int tokind = 0;
- X int in_comment = 0;
- X char quotechar;
- X
- X do {
- X#ifdef DEBUG
- X printf("eating whitespace\n");
- X#endif
- X while (is_white(buf[cp]))
- X ++cp;
- X#ifdef DEBUG
- X printf("cp = %4d buf[cp] = '%c'\n",cp,buf[cp]);
- X#endif
- X if (buf[cp] == NULL && fp != NULL) {
- X if (fgets(buf,BUFSIZE-1,fp) == NULL)
- X return(-1);
- X if (!in_comment) {
- X if (cpp_parse(buf,cpp_stack,symtab) < 0)
- X return(-1);
- X if (cpp_stack != NULL) {
- X if (!cpp_useline(cpp_stack,symtab)) {
- X buf[0] = ' ';
- X buf[1] = NULL;
- X }
- X }
- X }
- X cp = 0;
- X }
- X else if (buf[cp] == NULL) {
- X curtok[0] = NULL;
- X return(-1);
- X }
- X if (!in_comment) {
- X if (buf[cp] == '/' && buf[cp+1] == '*') {
- X in_comment = 1;
- X cp += 2;
- X }
- X }
- X else {
- X if (buf[cp] == '*' && buf[cp+1] == '/') {
- X in_comment = 0;
- X cp += 2;
- X }
- X else
- X cp++;
- X }
- X#ifdef DEBUG
- X printf("in_comment = %d\n",in_comment);
- X#endif
- X } while (is_white(buf[cp]) || in_comment);
- X sp = cp;
- X if (is_quote(buf[cp])) {
- X quotechar = buf[cp++];
- X curtok[tokind++] = quotechar;
- X quote = 1;
- X }
- X if ((is_tok_sep(buf[cp]) || buf[cp] == NULL) && quote == 0) {
- X curtok[tokind++] = buf[cp++];
- X if (curtok[tokind-1] == '<' && (buf[cp] == '>' ||
- X buf[cp] == '=')) {
- X curtok[tokind++] = buf[cp++];
- X } else if (curtok[tokind-1] == '>' && buf[cp] == '=') {
- X curtok[tokind++] = buf[cp++];
- X }
- X }
- X else {
- X while ((!is_tok_sep(buf[cp]) && !is_white(buf[cp]) &&
- X buf[cp] != NULL && quote == 0) ||
- X (buf[cp] != NULL && quote == 1)) {
- X if (quote == 1 && buf[cp] == '\\')
- X ++cp;
- X else if (quote == 1 && buf[cp] == quotechar)
- X break;
- X curtok[tokind++] = buf[cp++];
- X }
- X }
- X if (quote == 1) {
- X curtok[tokind++] = buf[cp++];
- X }
- X curtok[tokind] = NULL;
- X return(cp);
- X}
- X
- Xis_white(c)
- Xchar c;
- X{
- X return((c == '\t' || c == '\n' || c == ' '));
- X}
- X
- Xis_quote(c)
- Xchar c;
- X{
- X return((c == '\'' || c == '\"'));
- X}
- X
- Xis_tok_sep(c)
- Xchar c;
- X{
- X return((c == ',' || c == '(' ||
- X c == '#' || c == '!' ||
- X c == '-' || c == '+' ||
- X c == '*' || c == '/' ||
- X c == '>' || c == '<' ||
- X c == '=' || c == ';' ||
- X c == ';' || c == ')' ||
- X c == '[' || c == ']' ||
- X c == ':' || c == '\\' ||
- X c == '[' || c == ']'));
- X}
- X
- END-of-parse.c
- echo x - print_deps.c
- sed 's/^X//' >print_deps.c << 'END-of-print_deps.c'
- X#include <stdio.h>
- X#include "types.h"
- X
- Xprint_deps(make_list)
- XDNODE **make_list;
- X{
- X DNODE *dcur;
- X FNODE *fcur;
- X
- X for (dcur = *make_list; dcur != NULL; dcur = dcur->next) {
- X printf("\nThese files:\n");
- X for (fcur = dcur->dlist; fcur != NULL; fcur = fcur->next)
- X printf("\t%s\n",fcur->name);
- X printf("Depend on this file: %s\n",dcur->name);
- X }
- X}
- END-of-print_deps.c
- echo x - valid.c
- sed 's/^X//' >valid.c << 'END-of-valid.c'
- X/* valid.c */
- X
- X#include <stdio.h>
- X#include "types.h"
- X
- Xvalid_source_file(name)
- Xchar *name;
- X{
- X int i;
- X
- X for (i = 0; name[i] != NULL && name[i] != '.'; i++)
- X ;
- X if (name[i] == '.') {
- X if (!strcmp(&name[i+1],"c"))
- X return(CSOURCE);
- X if (!strcmp(&name[i+1],"h"))
- X return(CHEADER);
- X }
- X return(0);
- X}
- X
- END-of-valid.c
- exit
-
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-